package com.deimos.dataBase;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import com.spotimage.eosps.EOConstants.AcqStatus;
import org.vast.ows.OWSException;
import org.vast.ows.sps.StatusReport;
import org.vast.util.DateTime;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.deimos.UtilsDeimos;
import com.deimos_space.sps_cfi.jni.FeasibilityStudy;
import com.spotimage.eosps.EOReportHelper;
import com.vividsolutions.jts.geom.Coordinate;

import edu.emory.mathcs.backport.java.util.Arrays;
import edu.emory.mathcs.backport.java.util.Collections;

public class Scenario {
    private static List<Cloud> clouds = new ArrayList<Cloud>();
    private static List<Station> stations = new ArrayList<Station>();
    private static List<Sensor> sensors = new ArrayList<Sensor>();

    public static SimpleDateFormat DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");

    private static String scenarioFile;
    private static String scenarioDir = (new File(Cloud.class.getResource("Scenario.class").toString()).getParent() + "/../../../Scenarios").replace("file:", "");
    private static Date startTime;
    private static long offset = -1;
    private static long segmentLength = -1;
    public static boolean now = false; 

    public Scenario() {

    }

    public static boolean isScenarioEnabled() {
	return (scenarioFile != null);
    }

    private static Document getDocument(String filePath) {
	Document doc = null;
	try {
	    File file = new File(filePath);
	    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
	    DocumentBuilder db;
	    db = dbf.newDocumentBuilder();
	    doc = db.parse(file);
	    doc.getDocumentElement().normalize();
	    return doc;
	} catch (Exception e) {
	    return null;
	}
    }

    private static long parseOffset(Document doc) {
	long offset = -1;
	try {
	    NodeList nodeLst;
	    NodeList fstNmElmntLst;
	    Element fstNmElmnt;
	    NodeList fstNm;

	    nodeLst = doc.getElementsByTagName("ForceSegmentTime");

	    for (int s = 0; s < nodeLst.getLength(); s++) {
		Node fstNode = nodeLst.item(s);
		if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
		    Element fstElmnt = (Element) fstNode;
		    fstNmElmntLst = fstElmnt.getElementsByTagName("Offset");
		    fstNmElmnt = (Element) fstNmElmntLst.item(0);
		    fstNm = fstNmElmnt.getChildNodes();
		    offset = Long.parseLong((((Node) fstNm.item(0)).getNodeValue()));

		}

	    }
	} catch (Exception e) {
	    //e.printStackTrace();
	}
	return offset;
    }

    private static long parseSegmentLength(Document doc) {
	long segmentLength = -1;
	try {
	    NodeList nodeLst;
	    NodeList fstNmElmntLst;
	    Element fstNmElmnt;
	    NodeList fstNm;

	    nodeLst = doc.getElementsByTagName("ForceSegmentTime");

	    for (int s = 0; s < nodeLst.getLength(); s++) {
		Node fstNode = nodeLst.item(s);
		if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
		    Element fstElmnt = (Element) fstNode;
		    fstNmElmntLst = fstElmnt.getElementsByTagName("SegmentLength");
		    fstNmElmnt = (Element) fstNmElmntLst.item(0);
		    fstNm = fstNmElmnt.getChildNodes();
		    segmentLength = Long.parseLong((((Node) fstNm.item(0)).getNodeValue()));
		}

	    }
	} catch (Exception e) {
	   // e.printStackTrace();
	}
	return segmentLength;
    }


    private static List<Station> parseStations(Document doc) {
	List<Station> stations = new ArrayList<Station>();
	try {
	    NodeList nodeLst, nodeLst2;
	    NodeList fstNmElmntLst;
	    Element fstNmElmnt, fstNmElmnt2;
	    NodeList fstNm, fstNm2;

	    nodeLst = doc.getElementsByTagName("Station");

	    for (int s = 0; s < nodeLst.getLength(); s++) {
		Station station = new Station();
		Node fstNode = nodeLst.item(s);

		if (fstNode.getNodeType() == Node.ELEMENT_NODE) {

		    Element fstElmnt = (Element) fstNode;

		    fstNmElmntLst = fstElmnt.getElementsByTagName("StationId");
		    fstNmElmnt = (Element) fstNmElmntLst.item(0);
		    fstNm = fstNmElmnt.getChildNodes();
		    station.setStationId(((Node) fstNm.item(0)).getNodeValue());

		    nodeLst2 = fstElmnt.getElementsByTagName("Unavailabiltiy");

		    for (int i = 0; i < nodeLst2.getLength(); i++) {
			Unavailability unavailability = new Unavailability();
			Node fstNode2 = nodeLst2.item(i);

			if (fstNode2.getNodeType() == Node.ELEMENT_NODE) {

			    Element fstElmnt2 = (Element) fstNode2;

			    fstNmElmntLst = fstElmnt2.getElementsByTagName("Start");
			    fstNmElmnt2 = (Element) fstNmElmntLst.item(0);
			    fstNm2 = fstNmElmnt2.getChildNodes();
			    unavailability.setStart(Long.parseLong(((Node) fstNm2.item(0)).getNodeValue()));

			    fstNmElmntLst = fstElmnt2.getElementsByTagName("Stop");
			    fstNmElmnt2 = (Element) fstNmElmntLst.item(0);
			    fstNm2 = fstNmElmnt2.getChildNodes();
			    unavailability.setStop(Long.parseLong(((Node) fstNm2.item(0)).getNodeValue()));

			    fstNmElmntLst = fstElmnt2.getElementsByTagName("KnownAbout");
			    fstNmElmnt2 = (Element) fstNmElmntLst.item(0);
			    fstNm2 = fstNmElmnt2.getChildNodes();
			    unavailability.setKnownAbout(Long.parseLong(((Node) fstNm2.item(0)).getNodeValue()));
			    station.addUnavailability(unavailability);
			}
		    }
		    stations.add(station);
		}

	    }
	} catch (Exception e) {
	    e.printStackTrace();
	}
	return stations;
    }

    private static List<Sensor> parseSensor(Document doc) {
	List<Sensor> sensors = new ArrayList<Sensor>();
	try {
	    NodeList nodeLst, nodeLst2;
	    NodeList fstNmElmntLst;
	    Element fstNmElmnt, fstNmElmnt2;
	    NodeList fstNm, fstNm2;

	    nodeLst = doc.getElementsByTagName("Sensor");

	    for (int s = 0; s < nodeLst.getLength(); s++) {
		Sensor sensor = new Sensor();
		Node fstNode = nodeLst.item(s);

		if (fstNode.getNodeType() == Node.ELEMENT_NODE) {

		    Element fstElmnt = (Element) fstNode;

		    fstNmElmntLst = fstElmnt.getElementsByTagName("SensorId");
		    fstNmElmnt = (Element) fstNmElmntLst.item(0);
		    fstNm = fstNmElmnt.getChildNodes();
		    sensor.setSensorId(((Node) fstNm.item(0)).getNodeValue());

		    nodeLst2 = fstElmnt.getElementsByTagName("Unavailabiltiy");

		    for (int i = 0; i < nodeLst2.getLength(); i++) {
			Unavailability unavailability = new Unavailability();
			Node fstNode2 = nodeLst2.item(i);

			if (fstNode2.getNodeType() == Node.ELEMENT_NODE) {

			    Element fstElmnt2 = (Element) fstNode2;

			    fstNmElmntLst = fstElmnt2.getElementsByTagName("Start");
			    fstNmElmnt2 = (Element) fstNmElmntLst.item(0);
			    fstNm2 = fstNmElmnt2.getChildNodes();
			    unavailability.setStart(Long.parseLong(((Node) fstNm2.item(0)).getNodeValue()));

			    fstNmElmntLst = fstElmnt2.getElementsByTagName("Stop");
			    fstNmElmnt2 = (Element) fstNmElmntLst.item(0);
			    fstNm2 = fstNmElmnt2.getChildNodes();
			    unavailability.setStop(Long.parseLong(((Node) fstNm2.item(0)).getNodeValue()));

			    fstNmElmntLst = fstElmnt2.getElementsByTagName("KnownAbout");
			    fstNmElmnt2 = (Element) fstNmElmntLst.item(0);
			    fstNm2 = fstNmElmnt2.getChildNodes();
			    unavailability.setKnownAbout(Long.parseLong(((Node) fstNm2.item(0)).getNodeValue()));
			    sensor.addUnavailability(unavailability);
			}
		    }
		    sensors.add(sensor);
		}
	    }
	} catch (Exception e) {
	    e.printStackTrace();
	}
	return sensors;
    }

    private static List<Cloud> parseClouds(Document doc) {
	List<Cloud> clouds = new ArrayList<Cloud>();
	try {
	    NodeList nodeLst, nodeLst2;
	    NodeList fstNmElmntLst;
	    Element fstNmElmnt, fstNmElmnt2;
	    NodeList fstNm, fstNm2;

	    nodeLst = doc.getElementsByTagName("Cloud");

	    for (int s = 0; s < nodeLst.getLength(); s++) {
		Cloud cloud = new Cloud();
		Node fstNode = nodeLst.item(s);

		if (fstNode.getNodeType() == Node.ELEMENT_NODE) {

		    Element fstElmnt = (Element) fstNode;

		    fstNmElmntLst = fstElmnt.getElementsByTagName("CloudId");
		    fstNmElmnt = (Element) fstNmElmntLst.item(0);
		    fstNm = fstNmElmnt.getChildNodes();
		    cloud.setCloudId(Integer.parseInt(((Node) fstNm.item(0)).getNodeValue()));

		    fstNmElmntLst = fstElmnt.getElementsByTagName("Start");
		    fstNmElmnt = (Element) fstNmElmntLst.item(0);
		    fstNm = fstNmElmnt.getChildNodes();
		    cloud.setStart(Long.parseLong(((Node) fstNm.item(0)).getNodeValue()));

		    fstNmElmntLst = fstElmnt.getElementsByTagName("Stop");
		    fstNmElmnt = (Element) fstNmElmntLst.item(0);
		    fstNm = fstNmElmnt.getChildNodes();
		    cloud.setStop(Long.parseLong(((Node) fstNm.item(0)).getNodeValue()));

		    fstNmElmntLst = fstElmnt.getElementsByTagName("KnownAbout");
		    fstNmElmnt = (Element) fstNmElmntLst.item(0);
		    fstNm = fstNmElmnt.getChildNodes();
		    cloud.setKnownAbout(Long.parseLong(((Node) fstNm.item(0)).getNodeValue()));

		    fstNmElmntLst = fstElmnt.getElementsByTagName("Percentage");
		    fstNmElmnt = (Element) fstNmElmntLst.item(0);
		    fstNm = fstNmElmnt.getChildNodes();
		    cloud.setPercentage(Double.parseDouble(((Node) fstNm.item(0)).getNodeValue()));

		    nodeLst2 = ((Element) fstElmnt.getElementsByTagName("Region").item(0)).getElementsByTagName("Point");

		    for (int i = 0; i < nodeLst2.getLength(); i++) {
			Double x, y;
			Node fstNode2 = nodeLst2.item(i);

			if (fstNode2.getNodeType() == Node.ELEMENT_NODE) {

			    Element fstElmnt2 = (Element) fstNode2;

			    fstNmElmntLst = fstElmnt2.getElementsByTagName("Long");
			    fstNmElmnt2 = (Element) fstNmElmntLst.item(0);
			    fstNm2 = fstNmElmnt2.getChildNodes();
			    x = Double.parseDouble(((Node) fstNm2.item(0)).getNodeValue());

			    fstNmElmntLst = fstElmnt2.getElementsByTagName("Lat");
			    fstNmElmnt2 = (Element) fstNmElmntLst.item(0);
			    fstNm2 = fstNmElmnt2.getChildNodes();
			    y = Double.parseDouble(((Node) fstNm2.item(0)).getNodeValue());

			    cloud.addPoint(x, y);
			}

		    }
		    clouds.add(cloud);
		}

	    }
	} catch (Exception e) {
	    e.printStackTrace();
	}
	return clouds;
    }

    public String toString() {
	String text = "";
	text = "<Scenario>\n";

	for (Cloud cloud : clouds) {
	    text = text + cloud.toString("\t") + "\n";
	}

	for (Station station : stations) {
	    text = text + station.toString("\t") + "\n";
	}

	for (Sensor sensor : sensors) {
	    text = text + sensor.toString("\t") + "\n";
	}

	text = text + "</Scenario>";
	return text;
    }

    public static boolean setScenario(String scenarioId, Date startTime) {
	if (scenarioId.toLowerCase().compareTo("null") == 0) {
	    Scenario.scenarioFile = null;
	    return true;
	}
	Scenario.startTime = startTime;
	Scenario.scenarioFile = Scenario.scenarioDir + "/" + scenarioId + ".xml";
	File file = new File(Scenario.scenarioFile);
	if (!file.exists())
	    return false;

	Document doc = null;
	if ((doc = getDocument(Scenario.scenarioFile)) != null) {
	    clouds = parseClouds(doc);
	    stations = parseStations(doc);
	    sensors = parseSensor(doc);
	    offset = parseOffset(doc);
	    segmentLength = parseSegmentLength(doc);
	}

	return true;
    }

    @SuppressWarnings("unchecked")
    public static String getScenario(String scenarioId) {
	String response = "";
	try {
	    if (scenarioId.toLowerCase().compareTo("all") == 0) {
		File dir = new File(Scenario.scenarioDir);
		String[] files = dir.list();
		if (files == null || files.length == 0) {
		    response = "There are not Scenario files availables. ";
		} else {
		    response = "Availables Scenarios:\n\n";
		    List<String> filesOrder = Arrays.asList(files);
		    Collections.sort(filesOrder);
		    for (String file : filesOrder) {
			if (file.contains(".xml"))
			    response = response + file.replace(".xml", "") + "\n";
		    }

		}
	    } else if (scenarioId.toLowerCase().compareTo("current") == 0) {
		BufferedReader bf;
		bf = new BufferedReader(new FileReader(scenarioFile));
		String line;
		while ((line = bf.readLine()) != null)
		    response = response + line;
	    } else {
		BufferedReader bf;
		bf = new BufferedReader(new FileReader(Scenario.scenarioDir + "/" + scenarioId + ".xml"));
		String line;
		while ((line = bf.readLine()) != null)
		    response = response + line;
	    }
	} catch (Exception ex) {
	    response = "Scenario File unavailable. ";
	}
	return response;
    }

    public static ScenarioResponse getAvailability(EOReportHelper eohelper, StatusReport report, double maxCloud) {
	ScenarioResponse finalResponse = new ScenarioResponse();
	ScenarioResponse weatherResponse = new ScenarioResponse();
	ScenarioResponse sensorResponse = new ScenarioResponse();
	ScenarioResponse stationResponse = new ScenarioResponse();

	for (int s = 0; eohelper.getReportType() != null && s < eohelper.getNumSegments(); s++) {
	    Sensor sensor = null;
	    String instrument;
	    eohelper.loadSegment(s);
	    try {
		sensor = new Sensor(report.getSensorID());
		instrument = sensor.instrumentName;
	    } catch (OWSException e) {
		// TODO Auto-generated catch block
		return null;
	    }
	    if (maxCloud >= 0)
		sensor.setChance(maxCloud);

	    Date segStart;
	    Date segStop;
	    try {
		segStart = UtilsDeimos.sdf_hma.parse(eohelper.getAcquisitionStart().formatIso(0));
		segStop = UtilsDeimos.sdf_hma.parse(eohelper.getAcquisitionStop().formatIso(0));
	    } catch (ParseException e) {
		// TODO Auto-generated catch block
		return null;
	    }
	    Coordinate[] coordinates = eohelper.getFootprint().getCoordinates();

	    /*List<String> stationNames = new ArrayList<String>();
	    stationNames.add("North");
	    stationNames.add("South");*/
	    List<String> stationNames = sensor.getStations();

	    weatherResponse = weather(segStart, segStop, coordinates, sensor.getChance(), eohelper.getID());
	    sensorResponse = sensor(segStart, segStop, report.getSensorID(), instrument, eohelper.getID());

	    if (finalResponse.getDescription().compareTo("") == 0) {
		finalResponse = weatherResponse;
	    } else {
		finalResponse.setAvailable(finalResponse.isAvailable() && weatherResponse.isAvailable());
		finalResponse.setDescription(finalResponse.getDescription() + weatherResponse.getDescription());
	    }
	    finalResponse.setAvailable(finalResponse.isAvailable() && sensorResponse.isAvailable());
	    finalResponse.setDescription(finalResponse.getDescription() + sensorResponse.getDescription());

	    stationResponse = station(segStart, segStop, stationNames, eohelper.getID());
	    finalResponse.setAvailable(finalResponse.isAvailable() && stationResponse.isAvailable());
	    finalResponse.setDescription(finalResponse.getDescription() + stationResponse.getDescription());
	    if (eohelper.getObjectStatus() == AcqStatus.POTENTIAL || eohelper.getObjectStatus() == AcqStatus.PLANNED && (!weatherResponse.isAvailable() || !sensorResponse.isAvailable() || !stationResponse.isAvailable())) {
		finalResponse.addSegment(eohelper.getID());
	    }
	}

	return finalResponse;
    }

    public static void setTimes(FeasibilityStudy study, DateTime begin, DateTime end) {
	String DATE_FORMAT_CFI = "yyyy-MM-dd'_'HH:mm:ss.SSSSSS";
	SimpleDateFormat sdf_cfi = new SimpleDateFormat(DATE_FORMAT_CFI);
	if (now)
		startTime = new Date();
	if (offset == -1)
	    return;
	study.sort();
	try {
	    Date start = null;
	    start = startTime;
	    for (int i = 0; i < study.getSegments().size(); i++){
		String[] segment = study.getSegments().get(i);
		long duration = segmentLength * 1000;
		
		segment[0] = sdf_cfi.format(new Date(start.getTime() + (offset * 1000)));
		segment[1] = sdf_cfi.format(new Date(sdf_cfi.parse(segment[0]).getTime() + duration));
		
		if (i == 0) begin.setTime(new Date(start.getTime() + (offset * 1000)).getTime());
		if (i == study.getSegments().size() - 1) end.setTime(new Date(sdf_cfi.parse(segment[0]).getTime() + duration).getTime());
		start = sdf_cfi.parse(segment[1]);
	    }
	} catch (ParseException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
    }

    public static ScenarioResponse getSegmentAvailability(EOReportHelper eohelper, StatusReport report, double maxCloud) {
	ScenarioResponse finalResponse = new ScenarioResponse();
	ScenarioResponse weatherResponse = new ScenarioResponse();
	ScenarioResponse sensorResponse = new ScenarioResponse();
	ScenarioResponse stationResponse = new ScenarioResponse();
	Sensor sensor = null;
	String instrument;

	try {
	    sensor = new Sensor(report.getSensorID());
	    instrument = sensor.instrumentName;
	} catch (OWSException e) {
	    // TODO Auto-generated catch block
	    return null;
	}

	if (maxCloud >= 0)
	    sensor.setChance(maxCloud);

	Date segStart;
	Date segStop;
	try {
	    segStart = UtilsDeimos.sdf_hma.parse(eohelper.getAcquisitionStart().formatIso(0));
	    segStop = UtilsDeimos.sdf_hma.parse(eohelper.getAcquisitionStop().formatIso(0));
	} catch (ParseException e) {
	    // TODO Auto-generated catch block
	    return null;
	}
	Coordinate[] coordinates = eohelper.getFootprint().getCoordinates();

	/*List<String> stationNames = new ArrayList<String>();
	stationNames.add("North");
	stationNames.add("South");*/
	List<String> stationNames = sensor.getStations();

	weatherResponse = weather(segStart, segStop, coordinates, sensor.getChance(), eohelper.getID());
	sensorResponse = sensor(segStart, segStop, report.getSensorID(), instrument, eohelper.getID());

	if (finalResponse.getDescription().compareTo("") == 0) {
	    finalResponse = weatherResponse;
	} else {
	    finalResponse.setAvailable(finalResponse.isAvailable() && weatherResponse.isAvailable());
	    finalResponse.setDescription(finalResponse.getDescription() + weatherResponse.getDescription());
	}
	finalResponse.setAvailable(finalResponse.isAvailable() && sensorResponse.isAvailable());
	finalResponse.setDescription(finalResponse.getDescription() + sensorResponse.getDescription());

	stationResponse = station(segStart, segStop, stationNames, eohelper.getID());
	finalResponse.setAvailable(finalResponse.isAvailable() && stationResponse.isAvailable());
	finalResponse.setDescription(finalResponse.getDescription() + stationResponse.getDescription());
	if (eohelper.getObjectStatus() == AcqStatus.POTENTIAL || eohelper.getObjectStatus() == AcqStatus.PLANNED && (!weatherResponse.isAvailable() || !sensorResponse.isAvailable() || !stationResponse.isAvailable())) {
	    finalResponse.addSegment(eohelper.getID());
	}

	return finalResponse;
    }

    public static ScenarioResponse weather(Date start, Date stop, Coordinate[] coordinates, double maxChance, String segId) {
	ScenarioResponse finalResponse = new ScenarioResponse();

	for (Cloud cloud : clouds) {
	    /*
	     * System.out.println("Start: " + cloud.getStartTime(startTime));
	     * System.out.println("Stop: " + cloud.getStopTime(startTime));
	     * System.out.println("Know: " + cloud.getKnownTime(startTime));
	     * System.out.println("Start: " + start); System.out.println("");
	     */
	    if ((start.after(cloud.getStartTime(startTime)) && start.before(cloud.getStopTime(startTime))) || (stop.after(cloud.getStartTime(startTime)) && stop.before(cloud.getStopTime(startTime))) || (cloud.getStartTime(startTime).after(start) && cloud.getStartTime(startTime).before(stop)) || (cloud.getStopTime(startTime).after(start) && cloud.getStopTime(startTime).before(stop))) {
		for (int j = 0; j < coordinates.length; j++) {
		    if (cloud.contains(coordinates[j].x, coordinates[j].y)) {
			if ((new Date()).after(cloud.getKnownTime(startTime)) || ((new Date()).after(cloud.getStartTime(startTime)) && (new Date()).before(cloud.getStopTime(startTime)))) {

			    if (cloud.getPercentage() > finalResponse.getWeatherChance())
				finalResponse.setWeatherChance(cloud.getPercentage());
			}
		    }
		}
	    }
	}

	if (finalResponse.getWeatherChance() > maxChance) {
	    finalResponse.setAvailable(false);
	    finalResponse.setDescription("Percentage chance of bad weather (" + finalResponse.getWeatherChance() + "%) is over the max limit (" + maxChance + "%) for segment: " + segId + ". ");
	} else {
	    finalResponse.setDescription("The percentage chance of weather affecting the acquisition is: " + finalResponse.getWeatherChance() + " for segment " + segId + ". ");
	}
	return finalResponse;
    }

    public static ScenarioResponse sensor(Date start, Date stop, String sensorId, String instrument, String segid) {
	ScenarioResponse finalResponse = new ScenarioResponse();
	for (Sensor sensor : sensors) {
	    if (sensor.getSensorId().contains(sensorId)) {
		for (Unavailability unavailability : sensor.getUnavailabilities()) {
		    if ((start.after(unavailability.getStartTime(startTime)) && start.before(unavailability.getStopTime(startTime))) || (stop.after(unavailability.getStartTime(startTime)) && stop.before(unavailability.getStopTime(startTime))) || (unavailability.getStartTime(startTime).after(start) && unavailability.getStartTime(startTime).before(stop)) || (unavailability.getStopTime(startTime).after(start) && unavailability.getStopTime(startTime).before(stop))) {
			if ((new Date()).after(unavailability.getKnownTime(startTime)) || ((new Date()).after(unavailability.getStartTime(startTime)) && (new Date()).before(unavailability.getStopTime(startTime)))) {
			    finalResponse.setDescription(ScenarioResponse.Sensor_Unavailable, instrument, segid);
			    finalResponse.setAvailable(false);
			    return finalResponse;
			}
		    }

		}
	    }
	}

	finalResponse.setDescription(ScenarioResponse.Sensor_Available, instrument, segid);
	finalResponse.setAvailable(true);

	return finalResponse;
    }

    public static ScenarioResponse station(Date start, Date stop, List<String> stationNames, String segid) {
	ScenarioResponse finalResponse = new ScenarioResponse();
	String stationsAvailables = "";
	boolean stationNotAvailable;
	for (String stationId : stationNames) {
	    stationNotAvailable = false;
	    for (Station station : stations) {
		if (station.getStationId().toLowerCase().contains(stationId.toLowerCase())) {
		    for (Unavailability unavailability : station.getUnavailabilities()) {
			if ((start.after(unavailability.getStartTime(startTime)) && start.before(unavailability.getStopTime(startTime))) || (stop.after(unavailability.getStartTime(startTime)) && stop.before(unavailability.getStopTime(startTime))) || (unavailability.getStartTime(startTime).after(start) && unavailability.getStartTime(startTime).before(stop)) || (unavailability.getStopTime(startTime).after(start) && unavailability.getStopTime(startTime).before(stop))) {
			    if ((new Date()).after(unavailability.getKnownTime(startTime)) || ((new Date()).after(unavailability.getStartTime(startTime)) && (new Date()).before(unavailability.getStopTime(startTime)))) {
				stationNotAvailable = true;
			    }
			}

		    }
		}
	    }
	    if (!stationNotAvailable) {
		if (stationsAvailables == "")
		    stationsAvailables = stationId;
		else
		    stationsAvailables = stationsAvailables + ", " + stationId;
	    }
	}
	if (stationsAvailables == "") {
	    finalResponse.setDescription(ScenarioResponse.Station_Not_Available, segid);
	    finalResponse.setAvailable(false);
	} else {
	    finalResponse.setDescription(ScenarioResponse.Station_Available, stationsAvailables, segid);
	    finalResponse.setAvailable(true);
	}

	return finalResponse;
    }

}
